package com.zz.framework.core.utils

import android.app.Activity
import android.content.Context
import android.content.Intent
import android.net.Uri
import android.os.Bundle
import android.os.Parcelable
import androidx.annotation.AnimRes
import androidx.core.app.ActivityCompat
import androidx.fragment.app.Fragment
import com.skydoves.transformationlayout.TransformationCompat
import com.skydoves.transformationlayout.TransformationLayout
import com.zz.framework.R
import com.zz.framework.core.base.BaseUIFragment
import com.zz.framework.core.base.FragmentParentActivity
import java.io.Serializable
import java.util.*

/**
 * Copyright © 2019 zanezhao All rights reserved.
 * @author: zanezhao
 * @email: 1820022519@qq.com
 * @version: V1.0
 */
class IntentBuilder {
    var intent: Intent? = null
        private set
    private var mContext: Context? = null
    @AnimRes
    private var animOpen: Int = R.anim.right_in
    @AnimRes
    private var animExit: Int = R.anim.left_out

    constructor() {
        intent = Intent()
    }

    constructor(intent: Intent?) {
        var intent = intent
        intent = Intent(intent)
    }

    constructor(action: String?) {
        intent = Intent(action)
    }

    constructor(action: String?, uri: Uri?) {
        intent = Intent(action, uri)
    }

    constructor(packageContext: Context?, cls: Class<*>?) {
        mContext = packageContext
        intent = Intent(packageContext, cls)
    }

    constructor(action: String?, uri: Uri?, packageContext: Context?, cls: Class<*>?) {
        mContext = packageContext
        intent = Intent(action, uri, packageContext, cls)
    }

    fun setData(uri: Uri?): IntentBuilder {
        intent!!.data = uri
        return this
    }
    fun addFlags(flag: Int): IntentBuilder {
        intent!!.addFlags(flag)
        return this
    }

    val action: String?
        get() = intent!!.action

    val data: Uri?
        get() = intent!!.data

    val dataString: String?
        get() = intent!!.dataString

    val scheme: String?
        get() = intent!!.scheme

    val type: String?
        get() = intent!!.type

    fun setClass(packageContext: Context?, cls: Class<*>?): IntentBuilder {
        mContext = packageContext
        intent!!.setClass(mContext!!, cls!!)
        return this
    }

    fun putExtra(
        name: String?,
        value: Boolean
    ): IntentBuilder {
        intent!!.putExtra(name, value)
        return this
    }

    fun putExtra(
        name: String?,
        value: Byte
    ): IntentBuilder {
        intent!!.putExtra(name, value)
        return this
    }

    fun putExtra(
        name: String?,
        value: Char
    ): IntentBuilder {
        intent!!.putExtra(name, value)
        return this
    }

    fun putExtra(
        name: String?,
        value: Short
    ): IntentBuilder {
        intent!!.putExtra(name, value)
        return this
    }

    fun putExtra(name: String?, value: Int): IntentBuilder {
        intent!!.putExtra(name, value)
        return this
    }

    fun putExtra(
        name: String?,
        value: Long
    ): IntentBuilder {
        intent!!.putExtra(name, value)
        return this
    }

    fun putExtra(
        name: String?,
        value: Float
    ): IntentBuilder {
        intent!!.putExtra(name, value)
        return this
    }

    fun putExtra(
        name: String?,
        value: Double
    ): IntentBuilder {
        intent!!.putExtra(name, value)
        return this
    }

    fun putExtra(
        name: String?,
        value: String?
    ): IntentBuilder {
        intent!!.putExtra(name, value)
        return this
    }

    fun putExtra(
        name: String?,
        value: CharSequence?
    ): IntentBuilder {
        intent!!.putExtra(name, value)
        return this
    }

    fun putExtra(
        name: String?,
        value: Parcelable?
    ): IntentBuilder {
        intent!!.putExtra(name, value)
        return this
    }

    fun putExtra(
        name: String?,
        value: Array<Parcelable?>?
    ): IntentBuilder {
        intent!!.putExtra(name, value)
        return this
    }

    fun putParcelableArrayListExtra(
        name: String?,
        value: ArrayList<out Parcelable?>?
    ): IntentBuilder {
        intent!!.putExtra(name, value)
        return this
    }

    fun putIntegerArrayListExtra(
        name: String?,
        value: ArrayList<Int?>?
    ): IntentBuilder {
        intent!!.putExtra(name, value)
        return this
    }

    fun putStringArrayListExtra(
        name: String?,
        value: ArrayList<String?>?
    ): IntentBuilder {
        intent!!.putExtra(name, value)
        return this
    }

    fun putCharSequenceArrayListExtra(
        name: String?,
        value: ArrayList<CharSequence?>?
    ): IntentBuilder {
        intent!!.putExtra(name, value)
        return this
    }

    fun putExtra(
        name: String?,
        value: Serializable?
    ): IntentBuilder {
        intent!!.putExtra(name, value)
        return this
    }

    fun putExtra(
        name: String?,
        value: BooleanArray?
    ): IntentBuilder {
        intent!!.putExtra(name, value)
        return this
    }

    fun putExtra(
        name: String?,
        value: ByteArray?
    ): IntentBuilder {
        intent!!.putExtra(name, value)
        return this
    }

    fun putExtra(
        name: String?,
        value: ShortArray?
    ): IntentBuilder {
        intent!!.putExtra(name, value)
        return this
    }

    fun putExtra(
        name: String?,
        value: CharArray?
    ): IntentBuilder {
        intent!!.putExtra(name, value)
        return this
    }

    fun putExtra(
        name: String?,
        value: IntArray?
    ): IntentBuilder {
        intent!!.putExtra(name, value)
        return this
    }

    fun putExtra(
        name: String?,
        value: LongArray?
    ): IntentBuilder {
        intent!!.putExtra(name, value)
        return this
    }

    fun putExtra(
        name: String?,
        value: FloatArray?
    ): IntentBuilder {
        intent!!.putExtra(name, value)
        return this
    }

    fun putExtra(
        name: String?,
        value: DoubleArray?
    ): IntentBuilder {
        intent!!.putExtra(name, value)
        return this
    }

    fun putExtra(
        name: String?,
        value: Array<String?>?
    ): IntentBuilder {
        intent!!.putExtra(name, value)
        return this
    }

    fun putExtra(
        name: String?,
        value: Array<CharSequence?>?
    ): IntentBuilder {
        intent!!.putExtra(name, value)
        return this
    }

    fun putExtra(name: String?, value: Bundle?): IntentBuilder {
        intent!!.putExtra(name, value)
        return this
    }

    fun putExtras(src: Intent?): IntentBuilder {
        intent!!.putExtras(src!!)
        return this
    }

    fun putExtras(extras: Bundle?): IntentBuilder {
        intent!!.putExtras(extras!!)
        return this
    }

    fun setAction(action: String?): IntentBuilder {
        intent!!.action = action
        return this
    }

    fun setFlag(flag: Int): IntentBuilder {
        intent!!.flags = flag
        return this
    }


    fun finish(activity: Activity?): IntentBuilder {
        activity?.finish()
        return this
    }
    fun finishAfterTransition(activity: Activity?): IntentBuilder {
        activity?.finishAfterTransition()
        return this
    }

    fun overridePendingTransition(@AnimRes animOpen: Int, @AnimRes animExit: Int): IntentBuilder {
        this.animExit = animExit
        this.animOpen = animOpen
        return this
    }

    fun startActivity(): IntentBuilder {
        if (mContext != null) {
            mContext!!.startActivity(intent)
            (mContext as? Activity)?.overridePendingTransition(animOpen, animExit)
        }
        return this
    }

    fun startTransformationActivity(transformationLayout: TransformationLayout): IntentBuilder {
        intent?.let {
            TransformationCompat.startActivity(transformationLayout,it)
        }
        return this
    }
    fun startActivity(bundle: Bundle): IntentBuilder {
        if (mContext != null) {
            ActivityCompat.startActivity( mContext!!,intent!!, bundle)
        }
        return this
    }

    fun startActivityForResult(requestCode: Int): IntentBuilder {
        if (mContext != null) {
            (mContext as? Activity)?.startActivityForResult(intent, requestCode)
            (mContext as? Activity)?.overridePendingTransition(animOpen, animExit)
        }
        return this
    }

    fun startActivity(activity: Activity) {
        activity.startActivity(intent)
        activity.overridePendingTransition(animOpen, animExit)
    }

    fun startActivity(activity: Activity, isBack: Boolean) {
        activity.startActivity(intent)
        if (isBack) activity.overridePendingTransition(
            animOpen,
            animExit
        ) else activity.overridePendingTransition(animOpen, animExit)
    }

    fun startParentActivity(context: Activity?, clz: Class<out Fragment>?, isToolbar: Boolean) {
        context?.let {
            intent!!.setClass(context, FragmentParentActivity::class.java)
            intent!!.putExtra(FragmentParentActivity.KEY_FRAGMENT, clz)
            intent!!.putExtra(FragmentParentActivity.KEY_TOOLBAR, isToolbar)
            context.startActivity(intent)
            context.overridePendingTransition(animOpen, animExit)
        }
    }

    fun startParentActivity(context: Activity?, clazz: Class<out Fragment>) {
        context?.let {
            intent!!.setClass(context, FragmentParentActivity::class.java)
            intent!!.putExtra(FragmentParentActivity.KEY_FRAGMENT, clazz)
            context.startActivity(intent)
            context.overridePendingTransition(animOpen, animExit)
        }
    }

    fun startParentTransformationActivity(context: Activity?, transformationLayout:TransformationLayout,clazz: Class<out Fragment>) {
        context?.let {
            intent!!.setClass(context, FragmentParentActivity::class.java)
            intent!!.putExtra(FragmentParentActivity.KEY_FRAGMENT, clazz)
            TransformationCompat.startActivity(transformationLayout,intent!!)
        }
    }
    fun startParentActivity(context: Activity?, clazz: Class<out Fragment>,bundle: Bundle) {
        context?.let {
            intent!!.setClass(context, FragmentParentActivity::class.java)
            intent!!.putExtra(FragmentParentActivity.KEY_FRAGMENT, clazz)
            ActivityCompat.startActivity(it, intent!!, bundle)
        }
    }

    fun startParentActivity(fragment: Fragment?, clazz: Class<out Fragment>) {
        fragment?.requireActivity()?.let {
            intent!!.setClass(it, FragmentParentActivity::class.java)
            intent!!.putExtra(FragmentParentActivity.KEY_FRAGMENT, clazz)
            it.startActivity(intent)
            it.overridePendingTransition(animOpen, animExit)
        }
    }

    fun startParentActivity(fragment: Fragment?, clazz: Class<out Fragment>,bundle: Bundle) {
        fragment?.requireActivity()?.let {
            intent!!.setClass(it, FragmentParentActivity::class.java)
            intent!!.putExtra(FragmentParentActivity.KEY_FRAGMENT, clazz)
            ActivityCompat.startActivity(it, intent!!, bundle)
        }
    }

    fun startParentActivity(context: Activity?, clz: Class<out Fragment>?, requestCode: Int) {
        context?.let {
            intent!!.setClass(context, FragmentParentActivity::class.java)
            intent!!.putExtra(FragmentParentActivity.KEY_FRAGMENT, clz)
            context.startActivityForResult(intent, requestCode)
            context.overridePendingTransition(animOpen, animExit)
        }
    }

    fun startParentActivity(
        fragment: BaseUIFragment,
        clz: Class<out Fragment>?,
        requestCode: Int
    ) {
        intent!!.setClass(fragment.requireContext(), FragmentParentActivity::class.java)
        intent!!.putExtra(FragmentParentActivity.KEY_FRAGMENT, clz)
        fragment.startActivityForResult(intent, requestCode)
        fragment.getActivity()?.overridePendingTransition(animOpen, animExit)
    }

    companion object {
        const val EXTRA_HAS_TITLE = "EXTRA_HAS_TITLE"
        const val EXTRA_ADD_BACK_BUTTON = "EXTRA_ADD_BACK_BUTTON"
        const val ACTION_VIEW = "com.biz.action.VIEW"
        const val ACTION_VIEW_WEB = "com.biz.web.action.VIEW"
        const val KEY_USERNAME = "KEY_USERNAME"
        const val KEY_ID = "KEY_ID"
        const val KEY_TYPE = "KEY_TYPE"
        const val KEY_ADDRESS = "KEY_ADDRESS"
        const val KEY_INFO = "KEY_INFO"
        const val KEY_LIST = "KEY_LIST"
        const val KEY_TITLE = "KEY_TITLE"
        const val KEY_CONTENT = "KEY_CONTENT"
        const val KEY_AUTHOR = "KEY_AUTHOR"
        const val KEY_PAGE_TITLE = "KEY_PAGE_TITLE"
        const val KEY_FIELD = "KEY_FIELD"
        const val KEY_VALUE = "KEY_VALUE"
        const val KEY_CODE = "KEY_CODE"
        const val KEY_VALUE_NAME = "KEY_VALUE_NAME"
        const val KEY_KEY = "KEY_KEY"
        const val KEY_KEY1 = "KEY_KEY1"
        const val KEY_KEY2 = "KEY_KEY2"
        const val KEY_KEY3 = "KEY_KEY3"
        const val KEY_TAG = "KEY_TAG"
        const val KEY_DATA = "KEY_DATA"
        const val KEY_URL = "KEY_URL"
        const val KEY_POSITION = "KEY_POSITION"
        fun Builder(): IntentBuilder {
            return IntentBuilder()
        }

        fun Builder(intent: Intent?): IntentBuilder {
            return IntentBuilder(intent)
        }

        fun Builder(action: String?): IntentBuilder {
            return IntentBuilder(action)
        }

        fun Builder(
            action: String?,
            uri: Uri?
        ): IntentBuilder {
            return IntentBuilder(action, uri)
        }

        fun Builder(
            packageContext: Context?,
            cls: Class<*>?
        ): IntentBuilder {
            return IntentBuilder(packageContext, cls)
        }

        fun Builder(
            action: String?,
            uri: Uri?,
            packageContext: Context?,
            cls: Class<*>?
        ): IntentBuilder {
            return IntentBuilder(action, uri, packageContext, cls)
        }
    }
}